home *** CD-ROM | disk | FTP | other *** search
/ Komputer for Alle 1999 #5 / 1999 CD 5 (black).iso / Delphi3 / install / data.z / GAUGES.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-08-05  |  10.6 KB  |  412 lines

  1. unit Gauges;
  2.  
  3. interface
  4.  
  5. uses SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, StdCtrls;
  6.  
  7. type
  8.  
  9.   TGaugeKind = (gkText, gkHorizontalBar, gkVerticalBar, gkPie, gkNeedle);
  10.  
  11.   TGauge = class(TGraphicControl)
  12.   private
  13.     FMinValue: Longint;
  14.     FMaxValue: Longint;
  15.     FCurValue: Longint;
  16.     FKind: TGaugeKind;
  17.     FShowText: Boolean;
  18.     FBorderStyle: TBorderStyle;
  19.     FForeColor: TColor;
  20.     FBackColor: TColor;
  21.     procedure PaintBackground(AnImage: TBitmap);
  22.     procedure PaintAsText(AnImage: TBitmap; PaintRect: TRect);
  23.     procedure PaintAsNothing(AnImage: TBitmap; PaintRect: TRect);
  24.     procedure PaintAsBar(AnImage: TBitmap; PaintRect: TRect);
  25.     procedure PaintAsPie(AnImage: TBitmap; PaintRect: TRect);
  26.     procedure PaintAsNeedle(AnImage: TBitmap; PaintRect: TRect);
  27.     procedure SetGaugeKind(Value: TGaugeKind);
  28.     procedure SetShowText(Value: Boolean);
  29.     procedure SetBorderStyle(Value: TBorderStyle);
  30.     procedure SetForeColor(Value: TColor);
  31.     procedure SetBackColor(Value: TColor);
  32.     procedure SetMinValue(Value: Longint);
  33.     procedure SetMaxValue(Value: Longint);
  34.     procedure SetProgress(Value: Longint);
  35.     function GetPercentDone: Longint;
  36.   protected
  37.     procedure Paint; override;
  38.   public
  39.     constructor Create(AOwner: TComponent); override;
  40.     procedure AddProgress(Value: Longint);
  41.     property PercentDone: Longint read GetPercentDone;
  42.   published
  43.     property Align;
  44.     property Color;
  45.     property Enabled;
  46.     property Kind: TGaugeKind read FKind write SetGaugeKind default gkHorizontalBar;
  47.     property ShowText: Boolean read FShowText write SetShowText default True;
  48.     property Font;
  49.     property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
  50.     property ForeColor: TColor read FForeColor write SetForeColor default clBlack;
  51.     property BackColor: TColor read FBackColor write SetBackColor default clWhite;
  52.     property MinValue: Longint read FMinValue write SetMinValue default 0;
  53.     property MaxValue: Longint read FMaxValue write SetMaxValue default 100;
  54.     property ParentColor;
  55.     property ParentFont;
  56.     property ParentShowHint;
  57.     property PopupMenu;
  58.     property Progress: Longint read FCurValue write SetProgress;
  59.     property ShowHint;
  60.     property Visible;
  61.   end;
  62.  
  63. implementation
  64.  
  65. uses Consts;
  66.  
  67. type
  68.   TBltBitmap = class(TBitmap)
  69.     procedure MakeLike(ATemplate: TBitmap);
  70.   end;
  71.  
  72. { TBltBitmap }
  73.  
  74. procedure TBltBitmap.MakeLike(ATemplate: TBitmap);
  75. begin
  76.   Width := ATemplate.Width;
  77.   Height := ATemplate.Height;
  78.   Canvas.Brush.Color := clWindowFrame;
  79.   Canvas.Brush.Style := bsSolid;
  80.   Canvas.FillRect(Rect(0, 0, Width, Height));
  81. end;
  82.  
  83. { This function solves for x in the equation "x is y% of z". }
  84. function SolveForX(Y, Z: Longint): Longint;
  85. begin
  86.   Result := Trunc( Z * (Y * 0.01) );
  87. end;
  88.  
  89. { This function solves for y in the equation "x is y% of z". }
  90. function SolveForY(X, Z: Longint): Longint;
  91. begin
  92.   if Z = 0 then Result := 0
  93.   else Result := Trunc( (X * 100.0) / Z );
  94. end;
  95.  
  96. { TGauge }
  97.  
  98. constructor TGauge.Create(AOwner: TComponent);
  99. begin
  100.   inherited Create(AOwner);
  101.   ControlStyle := ControlStyle + [csFramed, csOpaque];
  102.   { default values }
  103.   FMinValue := 0;
  104.   FMaxValue := 100;
  105.   FCurValue := 0;
  106.   FKind := gkHorizontalBar;
  107.   FShowText := True;
  108.   FBorderStyle := bsSingle;
  109.   FForeColor := clBlack;
  110.   FBackColor := clWhite;
  111.   Width := 100;
  112.   Height := 100;
  113. end;
  114.  
  115. function TGauge.GetPercentDone: Longint;
  116. begin
  117.   Result := SolveForY(FCurValue - FMinValue, FMaxValue - FMinValue);
  118. end;
  119.  
  120. procedure TGauge.Paint;
  121. var
  122.   TheImage: TBitmap;
  123.   OverlayImage: TBltBitmap;
  124.   PaintRect: TRect;
  125. begin
  126.   with Canvas do
  127.   begin
  128.     TheImage := TBitmap.Create;
  129.     try
  130.       TheImage.Height := Height;
  131.       TheImage.Width := Width;
  132.       PaintBackground(TheImage);
  133.       PaintRect := ClientRect;
  134.       if FBorderStyle = bsSingle then InflateRect(PaintRect, -1, -1);
  135.       OverlayImage := TBltBitmap.Create;
  136.       try
  137.         OverlayImage.MakeLike(TheImage);
  138.         PaintBackground(OverlayImage);
  139.         case FKind of
  140.           gkText: PaintAsNothing(OverlayImage, PaintRect);
  141.           gkHorizontalBar, gkVerticalBar: PaintAsBar(OverlayImage, PaintRect);
  142.           gkPie: PaintAsPie(OverlayImage, PaintRect);
  143.           gkNeedle: PaintAsNeedle(OverlayImage, PaintRect);
  144.         end;
  145.         TheImage.Canvas.CopyMode := cmSrcInvert;
  146.         TheImage.Canvas.Draw(0, 0, OverlayImage);
  147.         TheImage.Canvas.CopyMode := cmSrcCopy;
  148.         if ShowText then PaintAsText(TheImage, PaintRect);
  149.       finally
  150.         OverlayImage.Free;
  151.       end;
  152.       Canvas.CopyMode := cmSrcCopy;
  153.       Canvas.Draw(0, 0, TheImage);
  154.     finally
  155.       TheImage.Destroy;
  156.     end;
  157.   end;
  158. end;
  159.  
  160. procedure TGauge.PaintBackground(AnImage: TBitmap);
  161. var
  162.   ARect: TRect;
  163. begin
  164.   with AnImage.Canvas do
  165.   begin
  166.     CopyMode := cmBlackness;
  167.     ARect := Rect(0, 0, Width, Height);
  168.     CopyRect(ARect, Animage.Canvas, ARect);
  169.     CopyMode := cmSrcCopy;
  170.   end;
  171. end;
  172.  
  173. procedure TGauge.PaintAsText(AnImage: TBitmap; PaintRect: TRect);
  174. var
  175.   S: string;
  176.   X, Y: Integer;
  177.   OverRect: TBltBitmap;
  178. begin
  179.   OverRect := TBltBitmap.Create;
  180.   try
  181.     OverRect.MakeLike(AnImage);
  182.     PaintBackground(OverRect);
  183.     S := Format('%d%%', [PercentDone]);
  184.     with OverRect.Canvas do
  185.     begin
  186.       Brush.Style := bsClear;
  187.       Font := Self.Font;
  188.       Font.Color := clWhite;
  189.       with PaintRect do
  190.       begin
  191.         X := (Right - Left + 1 - TextWidth(S)) div 2;
  192.         Y := (Bottom - Top + 1 - TextHeight(S)) div 2;
  193.       end;
  194.       TextRect(PaintRect, X, Y, S);
  195.     end;
  196.     AnImage.Canvas.CopyMode := cmSrcInvert;
  197.     AnImage.Canvas.Draw(0, 0, OverRect);
  198.   finally
  199.     OverRect.Free;
  200.   end;
  201. end;
  202.  
  203. procedure TGauge.PaintAsNothing(AnImage: TBitmap; PaintRect: TRect);
  204. begin
  205.   with AnImage do
  206.   begin
  207.     Canvas.Brush.Color := BackColor;
  208.     Canvas.FillRect(PaintRect);
  209.   end;
  210. end;
  211.  
  212. procedure TGauge.PaintAsBar(AnImage: TBitmap; PaintRect: TRect);
  213. var
  214.   FillSize: Longint;
  215.   W, H: Integer;
  216. begin
  217.   W := PaintRect.Right - PaintRect.Left + 1;
  218.   H := PaintRect.Bottom - PaintRect.Top + 1;
  219.   with AnImage.Canvas do
  220.   begin
  221.     Brush.Color := BackColor;
  222.     FillRect(PaintRect);
  223.     Pen.Color := ForeColor;
  224.     Pen.Width := 1;
  225.     Brush.Color := ForeColor;
  226.     case FKind of
  227.       gkHorizontalBar:
  228.         begin
  229.           FillSize := SolveForX(PercentDone, W);
  230.           if FillSize > W then FillSize := W;
  231.           if FillSize > 0 then FillRect(Rect(PaintRect.Left, PaintRect.Top,
  232.             FillSize, H));
  233.         end;
  234.       gkVerticalBar:
  235.         begin
  236.           FillSize := SolveForX(PercentDone, H);
  237.           if FillSize >= H then FillSize := H - 1;
  238.           FillRect(Rect(PaintRect.Left, H - FillSize, W, H));
  239.         end;
  240.     end;
  241.   end;
  242. end;
  243.  
  244. procedure TGauge.PaintAsPie(AnImage: TBitmap; PaintRect: TRect);
  245. var
  246.   MiddleX, MiddleY: Integer;
  247.   Angle: Double;
  248.   W, H: Integer;
  249. begin
  250.   W := PaintRect.Right - PaintRect.Left;
  251.   H := PaintRect.Bottom - PaintRect.Top;
  252.   if FBorderStyle = bsSingle then
  253.   begin
  254.     Inc(W);
  255.     Inc(H);
  256.   end;
  257.   with AnImage.Canvas do
  258.   begin
  259.     Brush.Color := Color;
  260.     FillRect(PaintRect);
  261.     Brush.Color := BackColor;
  262.     Pen.Color := ForeColor;
  263.     Pen.Width := 1;
  264.     Ellipse(PaintRect.Left, PaintRect.Top, W, H);
  265.     if PercentDone > 0 then
  266.     begin
  267.       Brush.Color := ForeColor;
  268.       MiddleX := W div 2;
  269.       MiddleY := H div 2;
  270.       Angle := (Pi * ((PercentDone / 50) + 0.5));
  271.       Pie(PaintRect.Left, PaintRect.Top, W, H, Round(MiddleX * (1 - Cos(Angle))),
  272.         Round(MiddleY * (1 - Sin(Angle))), MiddleX, 0);
  273.     end;
  274.   end;
  275. end;
  276.  
  277. procedure TGauge.PaintAsNeedle(AnImage: TBitmap; PaintRect: TRect);
  278. var
  279.   MiddleX: Integer;
  280.   Angle: Double;
  281.   X, Y, W, H: Integer;
  282. begin
  283.   with PaintRect do
  284.   begin
  285.     X := Left;
  286.     Y := Top;
  287.     W := Right - Left;
  288.     H := Bottom - Top;
  289.     if FBorderStyle = bsSingle then
  290.     begin
  291.       Inc(W);
  292.       Inc(H);
  293.     end;
  294.   end;
  295.   with AnImage.Canvas do
  296.   begin
  297.     Brush.Color := Color;
  298.     FillRect(PaintRect);
  299.     Brush.Color := BackColor;
  300.     Pen.Color := ForeColor;
  301.     Pen.Width := 1;
  302.     Pie(X, Y, W, H * 2 - 1, X + W, PaintRect.Bottom - 1, X, PaintRect.Bottom - 1);
  303.     MoveTo(X, PaintRect.Bottom);
  304.     LineTo(X + W, PaintRect.Bottom);
  305.     if PercentDone > 0 then
  306.     begin
  307.       Pen.Color := ForeColor;
  308.       MiddleX := Width div 2;
  309.       MoveTo(MiddleX, PaintRect.Bottom - 1);
  310.       Angle := (Pi * ((PercentDone / 100)));
  311.       LineTo(Round(MiddleX * (1 - Cos(Angle))), Round((PaintRect.Bottom - 1) *
  312.         (1 - Sin(Angle))));
  313.     end;
  314.   end;
  315. end;
  316.  
  317. procedure TGauge.SetGaugeKind(Value: TGaugeKind);
  318. begin
  319.   if Value <> FKind then
  320.   begin
  321.     FKind := Value;
  322.     Refresh;
  323.   end;
  324. end;
  325.  
  326. procedure TGauge.SetShowText(Value: Boolean);
  327. begin
  328.   if Value <> FShowText then
  329.   begin
  330.     FShowText := Value;
  331.     Refresh;
  332.   end;
  333. end;
  334.  
  335. procedure TGauge.SetBorderStyle(Value: TBorderStyle);
  336. begin
  337.   if Value <> FBorderStyle then
  338.   begin
  339.     FBorderStyle := Value;
  340.     Refresh;
  341.   end;
  342. end;
  343.  
  344. procedure TGauge.SetForeColor(Value: TColor);
  345. begin
  346.   if Value <> FForeColor then
  347.   begin
  348.     FForeColor := Value;
  349.     Refresh;
  350.   end;
  351. end;
  352.  
  353. procedure TGauge.SetBackColor(Value: TColor);
  354. begin
  355.   if Value <> FBackColor then
  356.   begin
  357.     FBackColor := Value;
  358.     Refresh;
  359.   end;
  360. end;
  361.  
  362. procedure TGauge.SetMinValue(Value: Longint);
  363. begin
  364.   if Value <> FMinValue then
  365.   begin
  366.     if Value > FMaxValue then
  367.       if not (csLoading in ComponentState) then
  368.         raise EInvalidOperation.CreateFmt(SOutOfRange, [-MaxInt, FMaxValue - 1]);
  369.     FMinValue := Value;
  370.     if FCurValue < Value then FCurValue := Value;
  371.     Refresh;
  372.   end;
  373. end;
  374.  
  375. procedure TGauge.SetMaxValue(Value: Longint);
  376. begin
  377.   if Value <> FMaxValue then
  378.   begin
  379.     if Value < FMinValue then
  380.       if not (csLoading in ComponentState) then
  381.         raise EInvalidOperation.CreateFmt(SOutOfRange, [FMinValue + 1, MaxInt]);
  382.     FMaxValue := Value;
  383.     if FCurValue > Value then FCurValue := Value;
  384.     Refresh;
  385.   end;
  386. end;
  387.  
  388. procedure TGauge.SetProgress(Value: Longint);
  389. var
  390.   TempPercent: Longint;
  391. begin
  392.   TempPercent := GetPercentDone;  { remember where we were }
  393.   if Value < FMinValue then
  394.     Value := FMinValue
  395.   else if Value > FMaxValue then
  396.     Value := FMaxValue;
  397.   if FCurValue <> Value then
  398.   begin
  399.     FCurValue := Value;
  400.     if TempPercent <> GetPercentDone then { only refresh if percentage changed }
  401.       Refresh;
  402.   end;
  403. end;
  404.  
  405. procedure TGauge.AddProgress(Value: Longint);
  406. begin
  407.   Progress := FCurValue + Value;
  408.   Refresh;
  409. end;
  410.  
  411. end.
  412.